#include "actor_client.h"
#include "TcpConnection.h"
#include "actor_packet.h"
#include "epoll_watch.h"
#include "packet.h"
#include <iostream>

as::md::ActorClient::ActorClient(as::net::EpollWatch *ep, as::net::Address &serverAddr, const char *name, int pri_key /*= 0*/)
	:TcpClient(ep, serverAddr, name), pri_key_(pri_key)
{
	this->SetMsgCallback(std::bind(&ActorClient::HandleConnMsg, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
	ep->AddTimer(std::bind(&ActorClient::RunTimer, this), 1000, 0);
	std::cout << "create client:" << name << std::endl;
}

as::md::ActorClient::~ActorClient()
{
	std::cout << "delete client!" << std::endl;
}

void as::md::ActorClient::SetRegisterActorCallback(RegisterActorFun fun)
{
	reg_actor_fun_ = fun;
}

void as::md::ActorClient::HandleConnMsg(as::net::TcpConnectionPtr &con, ByteBufferPtr &buf, int size)
{
	auto packetPtr = as::md::Packet::PacketData(buf);
	if (packetPtr == nullptr)
		return;

	uint32 sysId = packetPtr->sysId_;
	uint32 subId = packetPtr->subId_;
	auto body = packetPtr->body_;

	std::cout << "actor client handle msg conndId:" << con->GetConnId() << " fd:" << con->GetFd()
		<< " sysId:" << sysId << " subId:" << subId << std::endl;
	if (sysId == SYS_MSG)
	{
		if (subId == RespFrameId)
		{
			int frameId = 0;
			body->read_int32(frameId);
			remote_id_ = frameId;
			if (reg_actor_fun_)
			{
				reg_actor_fun_(frameId, this);
			}
			std::cout << "resp frameid:" << frameId << " connId:" << con->GetConnId() << std::endl;
		}
	}
}

void as::md::ActorClient::RunTimer()
{
	if (IsConn())
	{
		std::time_t ms = TimeValue::GetMsTime();
		if (ms > heart_time_)
		{
			heart_time_ = ms + 1000 * 10;

			/*as::md::ActorPacket packet(EMessageType::SYS_MSG, ESubMessageId::HeartBeat);
			SendMsg(&packet);*/

			if (remote_id_ == 0)
			{
				as::md::ActorPacket packet(EMessageType::SYS_MSG, ESubMessageId::ReqFrameId);
				packet.write_int32(pri_key_);
				SendMsg(&packet);
			}
		}

	}
}

void as::md::ActorClient::SendMsg(as::md::ActorPacket *packet)
{
	const char *buf = (const char*)packet->flust();
	Send(buf, packet->GetSize());
}

